import sys
sys.path.append("..//db")

import rnetdb
import time

# -- HELPERS -- #

def write_comment_header():
    fhdr.write("// %s\n"%("-"*80))

def write_comment_headline(name):
    fhdr.write("\n//\n// %s\n//\n\n"%name)

def write_comment_section(comment):
    lines = comment.splitlines()
    if len(lines) == 0:
        return

    fhdr.write("// %s \n" % ("=-" * 40))
    for line in lines:
        fhdr.write("// " + line + "\n")
    fhdr.write("// %s \n" % ("-=" * 40))

def write_endl():
    fhdr.write("\n")

def write_preprocessor(prefix, name, value):
    name.strip()
    name = name.replace(" ","_")
    name = name.upper()

    fhdr.write("#define RNET_%s_%s (%s)\n" % (prefix, name, value))

# Dump addresses
def write_dev_addresses(name, device_id):

    results = rnetdb.db.query(
        "SELECT * FROM [VIEW_DEVICES_ADDRS] "
        "WHERE device = " + rnetdb.sqlquote(device_id))

    write_comment_headline("Addresses")

    for x in results:
        write_preprocessor("ADDRESS",str(name) + " "  + str(x.endpoint) + " " + str(x.purpose),x.address)

def write_dev_caps(name, device_id):
   results = rnetdb.db.query(
        "SELECT * FROM [VIEW_DEVICES_CAPS] "
        "WHERE device = " + rnetdb.sqlquote(device_id))

   write_comment_headline("Capabillities")

   count = 0
   for x in results:
        count += 1

        fhdr.write("// Name          : %s\n"%x.cap_name.upper())
        fhdr.write("// Description   : %s\n"%x.cap_desc)
        fhdr.write("// Unit          : %s (%s)\n"% (x.unit,x.unit_name.upper()))
        write_preprocessor("CAP",str(name) + " " + str(x.cap_name),x.cap_id)
        write_endl()

   write_preprocessor("CAPS_CNT", str(name), count)


def write_dev_requests(name, device_id):
   results = rnetdb.db.query( \
        "SELECT * FROM [VIEW_DEVICE_REQUESTS] "
        "WHERE device = " + rnetdb.sqlquote(device_id))

   write_comment_headline("Requests")

   count = 0
   for x in results:
       count += 1

       fhdr.write("// Name          : %s\n" % x.request_name.upper())
       fhdr.write("// Description   : %s\n" % x.request_desc)
       fhdr.write("// Parameters    : %s (%s)\n" % (x.params_desc, x.params_format))
       fhdr.write("// Response      : %s\n"% x.response_desc)

       write_preprocessor("REQUEST",str(name) + " " + str(x.request_name),x.request_id)
       write_endl()

   write_preprocessor("REQUESTS_CNT", str(name), count)

# Dump devices
def write_devices():
    results = rnetdb.db.query(
        "SELECT * FROM [VIEW_DEVICES]" )

    write_endl()
    write_comment_section("Lists of devices")

    for x in results:
        write_endl()

        print "Device: %s Role: %s Location: %s"%(x.name, x.role, x.location)

        # Comment separator
        write_comment_header()

        fhdr.write("// Description   : %s\n" % x.desc)
        fhdr.write("// Role          : %s\n" % x.role)
        fhdr.write("// Location      : %s\n" % x.location)
        fhdr.write("// Created       : %s\n" % x.created)
        write_preprocessor("DEVICE", x.name, x.id)

        # Write information about device addresses
        write_dev_addresses(x.name, x.id)

        # Write information about device capabillities
        write_dev_caps(x.name, x.id)

        # Write information about device requests
        write_dev_requests(x.name, x.id)

        # Comment separator
        write_comment_header()
    write_endl()

# Dump endpoint addresses
def write_endpoints():
    pass

def write_units():
    results = rnetdb.db.query(
        "SELECT * FROM [VIEW_UNITS]")

    write_endl()
    write_comment_section("Lists of units")

    for x in results:
        print "Unit: %s Symbol: %s" % (x.name, x.symbol)
        fhdr.write("// Symbol    : %s\n" % x.symbol)
        fhdr.write("// Data type : %s (%s)\n" % (x.data_type, x.data_name))
        write_preprocessor("UNIT", x.name, x.id)
        write_preprocessor("UNIT", x.name + " type", x.data_type)
    write_endl()

def write_endpoints():
    results = rnetdb.db.query(
        "SELECT * FROM ENDPOINTS")

    write_endl()
    write_comment_section("Endpoints")

    for x in results:

        # How many addresses were registered for this enpoint
        res = rnetdb.db.query(
            "SELECT COUNT(*) AS count FROM ENDPOINT_ADDRS"
            " WHERE ENDPOINT_ADDRS.endpoint = %s" % x.id
        )

        cnt_addrs = res[0].count

        # How many devices were registered for this enpoint
        res = rnetdb.db.query(
            "SELECT COUNT(DISTINCT device) AS count FROM ENDPOINT_ADDRS"
            " WHERE ENDPOINT_ADDRS.endpoint = %s" % x.id
        )

        cnt_devs = res[0].count

        print "Endpoint: %s (%s) with %s devices (%s addresses)" % (x.name, x.id, cnt_devs, cnt_addrs)
        fhdr.write("// %s\n" % x.desc)
        fhdr.write("// Registered %s devices with %s addresses\n" % (cnt_devs, cnt_addrs))
        write_preprocessor("ENDPOINT", x.name, x.id)

    write_endl()

# Main routine
if __name__ == "__main__":

    # Setup database
    rnetdb.setup_sqlite('..//db//rnet.db')

    with open("RNet_Map.h", "w") as f:
        global fhdr
        fhdr = f

        fhdr.write("#ifndef _RNET_MAP_H_\n")
        fhdr.write("#define _RNET_MAP_H_\n")

        write_comment_section("Generated by hdrgen.py at %s" %
            time.strftime("%d/%m/%Y %H:%M:%S"))

        print "Writing devices"
        write_devices()

        print "Writing units"
        write_units()

        print "Writing endpoints"
        write_endpoints()

        # done
        write_endl()
        fhdr.write("#endif //_RNET_MAP_H_")
        print "Done."


